﻿using System.Collections.Generic;
using TrainGame.Model;

namespace TrainGame.AI.TileLay
{
	public class AiTileLay : AiMove
	{
		// lay this Tile in this Hex in this Rotation
		public Tile Tile;
		public GameboardHex Hex;
		public int Rotation;
		//public Hashtable NewRoutes;
		public List<string> NewRoutes = new List<string>();

		// this tile lay advances or detracts from long-term goals by this GoalValue
		public int GoalValue;

		public AiTileLay(Tile tile, GameboardHex hex, int rotation)
		{
			Tile = tile;
			Hex = hex;
			Rotation = rotation;
			//NewRoutes = (Hashtable) Hex.NewRoutes.Clone();
		}

		public override string ToString()
		{
			return string.Format("Tile {0} in hex {1} at rotation {2}", Tile.Name, Hex.Location, Rotation);
		}

		public string DescribeTileLay()
		{
			string s = "New route hexsides =";
			foreach (string side in NewRoutes)
				s += " " + side;
			return s;
		}

		/// <summary>
		/// Transfer tileLay.Hex.NewRoutes to tileLay.NewRoutes, converting from hash table to simple strings,
		/// taking into account tile rotation and which tracks the company can actually run on
		/// </summary>
		public void TransferHexNewRoutes(PublicCompany company, Gameboard gameboard)
		{
			// figure out the new routes through this hex
			// TODO: only check routes this company can reach (otherwise algorithm will value double towns too highly)
			//		 (And remove HACK below when fixing this)
			foreach (Side side in this.Hex.NewRoutes.Keys)
			{
				if (CanRunIntoTileFromSide(this.Hex, side, company, gameboard))
				{
					SideCollection destSides = (SideCollection)this.Hex.NewRoutes[side];
					foreach (Side dest in destSides)
					{
						Side realSide;
						if (dest.LetterOrCompass == Side.LetterOrCompassEnum.Letter)
						{
							// Joe: this never happens, they've always been converted to compass directions by this point
							realSide = new Side();
							realSide.ConvertToCompassWithRotation(dest, this.Rotation);
						}
						else
							realSide = dest;
						string direction = realSide.GetDirection();

						if (! this.NewRoutes.Contains(direction))
						{
							bool found = false;
							foreach (Side startSide in this.Hex.ExistingRoutes.Keys)
							{
								if (startSide.GetDirection() == direction)
									found = true;
							}
							if (!found)
								this.NewRoutes.Add(direction);
						}
					}
				}
			}
		}

		/// <summary>
		/// Can the company run to the 'side' hexside of the tile in this hex?
		/// </summary>
		/// <remarks>
		/// The hex and tile lay should have been validated before calling this method.
		/// We're concerned here with multi-route tiles (green and brown track tiles, double towns and separated-city tiles),
		/// where the company can only run on particular segments of track and not others.
		/// </remarks>
		/// <param name="hex"></param>
		/// <param name="side"></param>
		/// <param name="company"></param>
		/// <param name="gameboard"></param>
		/// <returns></returns>
		static private bool CanRunIntoTileFromSide(GameboardHex hex, Side side, PublicCompany company, Gameboard gameboard)
		{
			return true;	//TODO: fix this!
		}
	}
}
